package level

import (
	"fmt"
	"gitee.com/golang-module/carbon"
	"github.com/name5566/leaf/log"
	"math"
	"server/cfg"
	"server/game/bag"
	db3 "server/game/bag/db"
	"server/game/card"
	"server/game/player"
)

type LevelLogic struct {
	dao *LevelDao
}

func NewLevelLogic() *LevelLogic {
	return &LevelLogic{
		dao: NewLevelDao(),
	}
}
func (l *LevelLogic) GuanKaPeiXunShouRu(uid string) float32 {
	playerInfo, err := l.LevelInfo(uid)
	peiXunYuanGong := len(playerInfo.WanChengPeiXunCardIds)
	var base = 0
	if err != nil {

		return 0
	}
	for levelId := range playerInfo.LevelIds {
		base += int(cfg.ConfigData.TbGuanQia.Get(int32(levelId)).EarnAdd) * peiXunYuanGong
	}
	return float32(base)
}

// 提升关卡进度
func (l *LevelLogic) IncreaseLevelProgress(userID string, totalTalentAbility int) error {
	// 获取玩家关卡信息
	playerInfo, err := l.LevelInfo(userID)
	if err != nil {
		return err
	}

	// 获取当前关卡配置
	config := cfg.ConfigData.TbGuanQia.Get(int32(totalTalentAbility))

	// 计算消耗比例
	consumeRatio := math.Ceil(float64(config.TalentAbility) / float64(totalTalentAbility))
	actualConsumeMoney := int(config.MoneyConsume) * int(consumeRatio)

	// 这里需要实现扣除玩家钱币的逻辑，假设已经实现了 deductMoney 函数
	_, err = bag.EnUseItem(userID, db3.Chaopiao, actualConsumeMoney)
	if err != nil {
		return err
	}

	// 提升进度
	playerInfo.Progress++

	// 处理招工和培训逻辑，这里简单示意
	// 假设招工和培训次数是分开记录的，需要根据实际情况调整
	// 每次招工时只消耗钞票，不获得人才经验
	// 工人每次被培训时，消耗钞票，并获得人才经验
	// 工人完成培训时，获得角色阅历

	// 更新玩家关卡信息
	err = l.dao.updateUserLevelProgress(userID, playerInfo.Progress)
	if err != nil {
		return fmt.Errorf("更新玩家关卡信息失败: %v", err)
	}

	return nil
}
func (l *LevelLogic) BossBattle(userID string, totalTalentAbility int) (bool, error) {
	// 获取玩家关卡信息
	playerInfo, err := l.LevelInfo(userID)
	if err != nil {
		return false, err
	}

	// 获取当前关卡配置
	config := cfg.ConfigData.TbGuanQia.Get(int32(totalTalentAbility))

	// 检测人才总能力是否大于关底战配置的数值
	if totalTalentAbility > int(config.BossAbility) {
		// 通关，进入下一关
		playerInfo.LevelIds = append(playerInfo.LevelIds, playerInfo.CurrentLevel)
		playerInfo.CurrentLevel++
		playerInfo.Progress = 0
		err = l.dao.updateCurrentLevelProgressLevelIds(userID, playerInfo.CurrentLevel, playerInfo.Progress, playerInfo.LevelIds)
		if err != nil {
			return false, fmt.Errorf("更新玩家关卡信息失败: %v", err)
		}
		return true, nil
	}

	return false, nil
}
func (l *LevelLogic) initUserLevel(userId string) (UserLevelInfo, error) {
	levelInfo := UserLevelInfo{
		UserID:                      userId,
		CurrentLevel:                1,
		Progress:                    0,
		LevelIds:                    make([]int, 0),
		WanChengPeiXunGuanKaCardIds: make(map[int][]int),
		ZhaoGongList:                make(map[int64]ZhaoGongCard),
		WanChengPeiXunCardIds:       make([]int, 0),
	}
	err := l.dao.insert(levelInfo)
	if err != nil {
		return UserLevelInfo{}, err
	}
	return levelInfo, nil
}
func (l *LevelLogic) LevelInfo(userId string) (UserLevelInfo, error) {
	info, err := l.dao.userLevelInfo(userId)
	if err != nil {
		return l.initUserLevel(userId)
	}
	return info, nil
}
func (l *LevelLogic) ZhaoGong(uid string, cardId int64) (map[string]interface{}, error) {
	var ret = make(map[string]interface{}, 0)
	playerInfo, err := l.dao.GetPlayerLevelInfo(uid)
	if err != nil {
		return ret, err
	}
	config := cfg.ConfigData.TbGuanQia.Get(int32(playerInfo.CurrentLevel))
	if len(playerInfo.ZhaoGongList) >= int(config.Stuff) {
		return ret, fmt.Errorf("超过招工极限")
	}
	if _, ok := playerInfo.ZhaoGongList[cardId]; ok {
		return ret, fmt.Errorf("已经被招工了")
	}
	xiaoHaoBiLi := l.getXiaoHaoBiLi(uid)
	costNum := config.MoneyConsume * int32(xiaoHaoBiLi)
	var cardPeiXun = ZhaoGongCard{
		CardId:     cardId,
		PeiXunTime: 0,
	}
	playerInfo.ZhaoGongList[cardId] = cardPeiXun
	bagList, err := bag.EnUseItem(uid, db3.Chaopiao, int(costNum))
	if err != nil {
		return nil, err
	}
	err = l.dao.updatePeiXunIds(uid, playerInfo.ZhaoGongList)
	if err != nil {
		return nil, err
	}
	ret["level_info"] = playerInfo
	ret["bag_list"] = bagList
	return ret, nil
}
func (l *LevelLogic) PeiXun(uid string, cardId int64) (map[string]interface{}, error) {
	var ret = make(map[string]interface{}, 0)
	playerInfo, err := l.dao.GetPlayerLevelInfo(uid)
	if err != nil {
		return ret, err
	}
	zhaoGongList, ok := playerInfo.ZhaoGongList[cardId]
	if !ok {
		return ret, fmt.Errorf("没有在招工列表里，不能培训")
	}
	levelConfig := cfg.ConfigData.TbGuanQia.Get(int32(playerInfo.CurrentLevel))
	xiaoHaoBiLi := l.getXiaoHaoBiLi(uid)
	cardInfo, err := card.EnGetUserCardInfoByCardTId(uid, cardId)
	costNum := levelConfig.MoneyConsume * int32(xiaoHaoBiLi)
	_, err = bag.EnUseItem(uid, db3.Chaopiao, int(costNum))
	if err != nil {
		return nil, err
	}
	bagList, err := bag.EnAddItem(uid, db3.RencaiExp, int(levelConfig.ExpClip))
	if err != nil {
		return nil, err
	}
	zhaoGongList.PeiXunTime += zhaoGongList.PeiXunTime
	playerInfo.ZhaoGongList[cardId] = zhaoGongList
	err = l.dao.updatePeiXunIds(uid, playerInfo.ZhaoGongList)
	if err != nil {
		return nil, err
	}
	if playerInfo.ZhaoGongList[cardId].PeiXunTime >= int(levelConfig.Training) {
		playerInfo.WanChengPeiXunCardIds = append(playerInfo.WanChengPeiXunCardIds, int(cardInfo.CTId))
		playerInfo.WanChengPeiXunGuanKaCardIds[int(levelConfig.Id)] = append(playerInfo.WanChengPeiXunGuanKaCardIds[int(levelConfig.Id)], int(levelConfig.Id))
		userInfo, err := player.EnAddUserExp(uid, int(levelConfig.Yueli))
		if err != nil {
			log.Error("用户的人才经验没有添加 id是%s,经验是%d", uid, levelConfig.Yueli)
		}
		ret["user_info"] = userInfo
	}

	ret["level_info"] = playerInfo
	ret["bag_list"] = bagList
	return ret, nil
}
func (l *LevelLogic) getXiaoHaoBiLi(uid string) float64 {
	playerInfo, err := GetPlayerLevelInfo(uid)
	if err != nil {
		return 0
	}
	var wanJiaRenCaiNengLi = card.EnGetUserAllCardNengLi(uid)
	ceilValue := math.Ceil(float64(float32(cfg.ConfigData.TbGuanQia.Get(int32(playerInfo.CurrentLevel)).TalentAbility) / wanJiaRenCaiNengLi))
	return ceilValue
}

func (l *LevelLogic) JiLi(userId string) (map[string]interface{}, error) {
	var ret = make(map[string]interface{}, 0)
	playerInfo, err := l.dao.GetPlayerLevelInfo(userId)
	if err != nil {
		return ret, err
	}
	if carbon.CreateFromTimestamp(playerInfo.JiLiTime).DiffAbsInSeconds(carbon.Now()) > 0 {
		return ret, fmt.Errorf("")
	}
	playerInfo.JiLiTime = carbon.Now().AddHours(4).Timestamp()
	l.dao.updateJiLiTime(userId, playerInfo.JiLiTime)
	return ret, nil
}
